/*
 * Roler.cpp
 *
 *  Created on: 2015-9-22
 *      Author: 10095427
 */

#include "Roler.h"

#define   WIDTH   16
#define   HEIGHT   16
#define   MOVE_TIME_GAP  0.2
#define   ONE_STEP_TIME  0.5

#define TALK_BG_X          (-24)
#define TALK_BG_Y          16
#define CONTENT_X          (-22)
#define CONTENT_Y          18
#define CONTENT_WIDTH      60
#define CONTENT_HEIGHT     44
#define CONTENT_FONT_SIZE  8
#define CONTENT_FONT_NAME  "arial"
#define CONTENT_COLOR      (Color3B::BLACK)
#define TALK_DELAY_TIME    2
#define ACTION_Y           16

typedef enum {
    ZBg,
    ZRoler,
    ZTalkBg,
    ZTalkContent,
    ZAction,


} ZIndex;

typedef enum {
    TagTalkBg = 10,
    TagTalkContent,



} TagType;

Roler::Roler()
:m_type(0)
,m_rolerSprite(NULL)
,m_callback(NULL)
,m_isTalk(false)
{


}

Roler::~Roler() {
    m_moveActionsArray->removeAllObjects();
    CC_SAFE_RELEASE_NULL(m_moveActionsArray);
}

Roler* Roler::create(int type)
{
	Roler *pRet = new(std::nothrow) Roler();
    if (pRet && pRet->init(type)){
        pRet->autorelease();
        return pRet;
    }
    else
    {
        delete pRet;
        pRet = NULL;
        return NULL;
    }
}

bool Roler::init(int type)
{
    if (!Layer::init()) {
        return false;
    }
    m_type = type;
    moveActionInit();
    return true;
}

void Roler::moveActionInit()
{
	Texture2D *tempTexture = Director::getInstance()->getTextureCache()->addImage(getFileByType());
	SpriteFrame *tempFrame = SpriteFrame::createWithTexture(tempTexture, Rect(0,0,WIDTH,HEIGHT));
	m_rolerSprite = Sprite::createWithSpriteFrame(tempFrame);
	m_rolerSprite->setAnchorPoint(Vec2::ZERO);
	m_rolerSprite->setPosition(Vec2::ZERO);

	m_moveActionsArray = __Array::create();
    m_moveActionsArray->retain();
	Vector<cocos2d::SpriteFrame *> tempFrames;
	for (int i=0; i<4; i++){
	    tempFrames.clear();
	    for (int j=0; j<4; j++)
	    {
	        auto frame = SpriteFrame::createWithTexture(tempTexture, Rect(j*WIDTH,i*HEIGHT,WIDTH,HEIGHT));
	        tempFrames.pushBack(frame);
	    }
	    auto tempAnimation = Animation::createWithSpriteFrames(tempFrames, MOVE_TIME_GAP);
	    Animate* tempAction = Animate::create(tempAnimation);
	    m_moveActionsArray->addObject(tempAction);
    }
	m_rolerSprite->runAction(RepeatForever::create((Animate *)m_moveActionsArray->getObjectAtIndex(0)));
	addChild(m_rolerSprite,ZRoler);

}

const char* Roler::getFileByType()
{
	switch(m_type){
	    case RolerTypePrincess:
	    	return "Role01.png";
        case RolerTypePrince:
            return "Role02.png";
        case RolerTypeBoss1:
            return "Role03.png";
        case RolerTypeMonster1:
            return "Role04.png";
        case RolerTypeMonster2:
            return "Role05.png";
	}
	return "";
}

void Roler::move(int direct,int steps)
{
	setDirection(direct);
	switch(direct){
	case RolerDirectDown:
		this->runAction(Sequence::create(MoveTo::create(ONE_STEP_TIME*steps,
				Point(this->getPosition().x,this->getPosition().y-steps*HEIGHT)),
				CallFuncN::create(CC_CALLBACK_1(Roler::moveEndCallback, this)),
			        		                           NULL));
		break;
	case RolerDirectLeft:
		this->runAction(Sequence::create(MoveTo::create(ONE_STEP_TIME*steps,
				Point(this->getPosition().x-steps*WIDTH,this->getPosition().y)),
				CallFuncN::create(CC_CALLBACK_1(Roler::moveEndCallback, this)),
			        		                           NULL));
		break;
	case RolerDirectRight:
		this->runAction(Sequence::create(MoveTo::create(ONE_STEP_TIME*steps,
				Point(this->getPosition().x+steps*WIDTH,this->getPosition().y)),
				CallFuncN::create(CC_CALLBACK_1(Roler::moveEndCallback, this)),
			        		                           NULL));
		break;
	case RolerDirectUp:
		this->runAction(Sequence::create(MoveTo::create(ONE_STEP_TIME*steps,
				Point(this->getPosition().x,this->getPosition().y+steps*HEIGHT)),
				CallFuncN::create(CC_CALLBACK_1(Roler::moveEndCallback, this)),
			        		                           NULL));
		break;
	}
}

void Roler::setDirection(int direct)
{
	m_rolerSprite->stopAllActions();
	m_rolerSprite->runAction(RepeatForever::create((Animate *)m_moveActionsArray->getObjectAtIndex(direct)));
}

void Roler::setCallback(const rolerMoveEndCallback& callback)
{
	m_callback = callback;
}

void Roler::moveEndCallback(Node *node)
{
	m_callback(this);
}

void Roler::moveAndNoDirectionChange(int direct,int steps)
{
	switch(direct){
	case RolerDirectDown:
		this->runAction(Sequence::create(MoveTo::create(ONE_STEP_TIME*steps,
				Point(this->getPosition().x,this->getPosition().y-steps*HEIGHT)),
				CallFuncN::create(CC_CALLBACK_1(Roler::moveEndCallback, this)),
			        		                           NULL));
		break;
	case RolerDirectLeft:
		this->runAction(Sequence::create(MoveTo::create(ONE_STEP_TIME*steps,
				Point(this->getPosition().x-steps*WIDTH,this->getPosition().y)),
				CallFuncN::create(CC_CALLBACK_1(Roler::moveEndCallback, this)),
			        		                           NULL));
		break;
	case RolerDirectRight:
		this->runAction(Sequence::create(MoveTo::create(ONE_STEP_TIME*steps,
				Point(this->getPosition().x+steps*WIDTH,this->getPosition().y)),
				CallFuncN::create(CC_CALLBACK_1(Roler::moveEndCallback, this)),
			        		                           NULL));
		break;
	case RolerDirectUp:
		this->runAction(Sequence::create(MoveTo::create(ONE_STEP_TIME*steps,
				Point(this->getPosition().x,this->getPosition().y+steps*HEIGHT)),
				CallFuncN::create(CC_CALLBACK_1(Roler::moveEndCallback, this)),
			        		                           NULL));
		break;
	}
}

void Roler::talk(const char* content)
{
	auto talkBg = Sprite::create("TalkBg.png");
	talkBg->setAnchorPoint(Vec2::ZERO);
	talkBg->setPosition(TALK_BG_X,TALK_BG_Y);
	talkBg->setTag(TagTalkBg);
	addChild(talkBg,ZTalkBg);

	talkBg->runAction(Sequence::create(DelayTime::create(TALK_DELAY_TIME),
			CallFunc::create(CC_CALLBACK_0(Sprite::removeFromParent, talkBg)),
		        		                           NULL));

	LabelTTF *contentLabel = LabelTTF::create(content,CONTENT_FONT_NAME,CONTENT_FONT_SIZE,
			                 Size(CONTENT_WIDTH,CONTENT_HEIGHT));
	contentLabel->setAnchorPoint(Vec2::ZERO);
	contentLabel->setPosition(CONTENT_X,CONTENT_Y);
	contentLabel->setTag(TagTalkContent);
	contentLabel->setColor(CONTENT_COLOR);
	addChild(contentLabel,ZTalkContent);
	contentLabel->runAction(Sequence::create(DelayTime::create(TALK_DELAY_TIME),
			CallFunc::create(CC_CALLBACK_0(Sprite::removeFromParent, contentLabel)),
			CallFuncN::create(CC_CALLBACK_1(Roler::talkEndCallback, this)),
		        		                           NULL));
	m_isTalk = true;
}

void Roler::talkEndCallback(Node *node)
{
	m_callback(this);
	m_isTalk = false;
}

void Roler::showAction(int type)
{
	auto action = Sprite::create(getActionFileNameByType(type));
	action->setAnchorPoint(Vec2::ZERO);
	action->setPosition((WIDTH - action->getContentSize().width)/2,ACTION_Y);
	addChild(action,ZAction);
	action->runAction(Sequence::create(DelayTime::create(TALK_DELAY_TIME),
			CallFunc::create(CC_CALLBACK_0(Sprite::removeFromParent, action)),
			CallFuncN::create(CC_CALLBACK_1(Roler::actionEndCallback, this)),
		        		                           NULL));
}

void Roler::actionEndCallback(Node *node)
{
	m_callback(this);
}

const char* Roler::getActionFileNameByType(int type)
{
	switch(type){
	    case RolerActionTypeQuery:
	    	return "Query.png";
	}
	return "";
}

